package gw.com.android.presenter.http;

import android.text.TextUtils;
import android.util.Base64;

import org.json.JSONObject;

import java.io.IOException;

import gw.com.android.app.AppMain;
import gw.com.android.app.GTConfig;
import gw.com.android.model.ConfigUtil;
import gw.com.android.utils.ThreadPool;
import okhttp3.Response;
import www.com.library.app.Logger;
import www.com.library.interfaces.ReqCallBack;

/**
 * 直播间的接口，需要token
 *
 * @author jett
 * @since 2018-03-02.
 */
public abstract class BaseChatRequest<T> {

    private final String PREF_TRADE_NEWS_TOKEN = "pref_jiepan_token";

    public void call(final ReqCallBack<T> callBack) {
        ThreadPool.getInstance().submit(new Runnable() {
            @Override
            public void run() {
                try {
                    T data = sendRequest();
                    sendSuccess(callBack, data);
                } catch (IOException e) {
                    sendFailure(callBack, e);
                }
            }
        });
    }

    protected abstract T sendRequest() throws IOException;

    protected String acquireToken() {
        String token = getLocalToken();
        if (TextUtils.isEmpty(token)) {
            return requestToken();
        }
        return token;
    }

    protected boolean isResponseInvalidToken(String str) {
        if (!TextUtils.isEmpty(str)) {
            try {
                JSONObject jsonObject = new JSONObject(str);
                return "invalid_token".equals(jsonObject.optString("error"));
            } catch (Exception ignore) {
            }
        }
        return false;
    }

    private String getLocalToken() {
        String value = GTConfig.instance().getStringValue(PREF_TRADE_NEWS_TOKEN);
        if (!TextUtils.isEmpty(value)) {
            String[] strs = value.split("::");
            if (strs.length > 1) {
                String token = strs[0];
                long expires = Long.parseLong(strs[1]);
                if (System.currentTimeMillis() < expires) {
                    return token;
                }
            }
            GTConfig.instance().setStringValue(PREF_TRADE_NEWS_TOKEN, null);
        }
        return null;
    }

    protected String requestToken() {
        try {
            //String tokenUrl = "https://ms-beta.5kwords.com/oauth/token?grant_type=password&username=netkiller@msn.com&password=123456";
            String tokenUrl = ConfigUtil.instance().getUrlPath("financeToken");
            String head = "Basic " + Base64.encodeToString("api:secret".getBytes(), Base64.NO_WRAP);
            Response response = new Https().url(tokenUrl).addHeader("Authorization", head).post();
            String result = response.body().string();
            if (!response.isSuccessful()) {
                return null;
            }
            JSONObject json = new JSONObject(result);
            String token = json.optString("access_token");
            if (!TextUtils.isEmpty(token)) {
                int expires = json.optInt("expires_in");
                saveToken(token, expires);
                return token;
            }
        } catch (Exception e) {
            Logger.e(e);
        }
        return null;
    }

    private void saveToken(String token, long expires) {
        if (expires <= 0) {
            return;
        }
        long expiresMillis = System.currentTimeMillis() + expires * 1000;
        String value = token + "::" + expiresMillis;
        GTConfig.instance().setStringValue(PREF_TRADE_NEWS_TOKEN, value);
    }

    protected void sendSuccess(final ReqCallBack<T> callBack, final T data) {
        AppMain.getApp().getHandler().post(new Runnable() {
            @Override
            public void run() {
                if (callBack != null) {
                    callBack.onReqSuccess(data);
                }
            }
        });
    }

    protected void sendFailure(final ReqCallBack<T> callBack, final Exception e) {
        AppMain.getApp().getHandler().post(new Runnable() {
            @Override
            public void run() {
                if (callBack != null) {
                    callBack.onReqFailed(e == null ? null : e.getMessage());
                }
            }
        });
    }

}
